﻿// ===========================================
// Author: Shaun Danielz
// Create Date: 2012/03/21
// Solution:Series Organiser
// Project:SeriesOrganiser.Library
// FileName:Organiser.cs
// Purpose:
// Copyright: 2012
// ===========================================

using System;
using System.IO;

namespace SeriesOrganiser.Library
{
    /// <summary>
    /// This is the main class of the project.
    /// </summary>
    /// <remarks>
    /// It is responsible for moving the series files from the
    /// input directory to the series folder.
    /// </remarks>
    public class Organiser
    {
        /// <summary>
        /// Command line arguments
        /// </summary>
        private readonly string[] _args;

        /// <summary>
        /// The total number of files that have been moved to the
        /// series folder.
        /// </summary>
        private int _filesMovedTotal;

        /// <summary>
        /// The input directory where the series are stored.
        /// </summary>
        /// <remarks>
        /// This is passed in as a command argument
        /// </remarks>
        private string _inputDirectory;

        /// <summary>
        /// The output directory where the series are stored.
        /// </summary>
        /// <remarks>
        /// This is passed in as a command argument
        /// </remarks>
        private string _outputDirectory;

        #region  Constructors 

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="args">args from the command line</param>
        public Organiser(string[] args)
        {
            _args = args;
        }

        #endregion

        /// <summary>
        /// Organises your input folder.
        /// </summary>
        public void Organise()
        {
            if (!ValidateCommandArguments())
                return; // stop

            foreach (string inputFile in Directory.GetFiles(_inputDirectory))
            {
                MoveFile(inputFile);
            }

            Console.WriteLine("Total number of files moved: {0}", _filesMovedTotal);
        }

        /// <summary>
        /// Moves the input file to the output series folder.
        /// </summary>
        /// <param name="inputFile"></param>
        private void MoveFile(string inputFile)
        {
            var inputFileName = Path.GetFileName(inputFile);
            if (string.IsNullOrEmpty(inputFileName))
                return; // stop

            // find the season indicator text. I.E S01E01
            int seasonIndex = inputFileName.IndexOf("S0", StringComparison.Ordinal);
            if (seasonIndex < 0)
            {
                // we try find a series than has more than 10 seasons
                seasonIndex = inputFileName.IndexOf("S1", StringComparison.Ordinal);
                if (seasonIndex < 0)
                    return; // stop
            }

            // get season name
            string seasonNumber = inputFileName.Substring(seasonIndex, 3);
            // do a sainity check
            if (seasonNumber.Length < 3)
                return; // stop
            seasonNumber = seasonNumber.Replace("S", "");
            // remove leading zero if season is less than 10
            if (seasonNumber[0] == '0')
                seasonNumber = seasonNumber.Replace("0", "");
            string seasonName = string.Format("Season {0}", seasonNumber);

            // get the show name
            string showName = inputFileName.Substring(0, seasonIndex - 1);
            showName = showName.Replace(".", " ");

            // create show name folder 
            string showNameFolder = Path.Combine(_outputDirectory, showName);
            if (!Directory.Exists(showNameFolder))
                Directory.CreateDirectory(showNameFolder);

            // create season folder
            string seasonFolderName = Path.Combine(showNameFolder, seasonName);
            if (!Directory.Exists(seasonFolderName))
                Directory.CreateDirectory(seasonFolderName);

            // don't copy the file if it already exists.
            var seriesFileName = Path.Combine(seasonFolderName, inputFileName);
            if (File.Exists(seriesFileName))
                return; // stop

            // move input file
            File.Move(inputFile, seriesFileName);

            _filesMovedTotal++;
            Console.WriteLine("[{0}] {1} has been moved to the series folder", DateTime.Now, Path.GetFileName(inputFile));
        }


        /// <summary>
        /// Validates the arguments passed into the console app
        /// </summary>
        /// <returns>True if valid. False if the arguments violate business rules.</returns>
        private bool ValidateCommandArguments()
        {
            if (_args == null || _args.Length < 2)
            {
                ApplicationUsage.Show();
                return false;
            }

            _inputDirectory = _args[0];
            if (!Directory.Exists(_inputDirectory))
            {
                Console.WriteLine("{0} input directory does not exist", _inputDirectory);
                return false;
            }

            _outputDirectory = _args[1];
            if (!Directory.Exists(_outputDirectory))
            {
                Console.WriteLine("{0} output directory does not exist", _outputDirectory);
                return false;
            }

            // no errors
            return true;
        }

        #region Private Method
    }

    #endregion
}